package org.etherframework.tests.features.mediator
{
	import org.etherframework.core.IModule;
	import org.etherframework.mediator.IMediators;
	import org.etherframework.tests.features.mediator.mediators.ActivatableMediator;
	import org.etherframework.tests.features.mediator.mediators.LifecycledMediator;
	import org.etherframework.tests.features.mediator.views.TrivialView;
	import org.etherframework.tests.utils.ModuleInfo;
	import org.etherframework.tests.utils.TestUtility;
	import org.flexunit.async.Async;
	import org.fluint.uiImpersonation.UIImpersonator;
	import org.hamcrest.assertThat;
	import org.hamcrest.collection.array;
	import org.hamcrest.object.isFalse;
	import org.hamcrest.object.isTrue;
	
	import spark.components.Group;

	public class when_using_activatable_mediator
	{	
		private static var _testUtility:TestUtility = new TestUtility();
		private static var _module:IModule;
		private static var _mediator:ActivatableMediator;
		private static var _m:IMediators;
		private static var _moduleView:Group;
		private static var _moduleNestedView:Group;
		private static var _info:ModuleInfo;
		private static var _view:TrivialView;
		private static var _pendentView:TrivialView;
		private static var _pendentMediator:ActivatableMediator;
		
		[BeforeClass(async)]
		public static function setUpBeforeClass():void
		{
			_moduleView = UIImpersonator.addChild(new Group()) as Group;
			_info = _testUtility.createModuleInfo(null, _moduleView);
			_moduleNestedView = new Group();
			_module = _info.module;
			_m = _module.mediators;
			_view = new TrivialView();
			_pendentView = new TrivialView();
			
			_m.addMediator(TrivialView, ActivatableMediator);
			
			_moduleView.addElement(_view);
			_mediator = _m.hasMediator(_view) as ActivatableMediator;
			
			_moduleNestedView.addElement(_pendentView);
			_pendentMediator = _m.createMediator(_pendentView) as ActivatableMediator;
			
			Async.delayCall(when_using_activatable_mediator, function():void{}, 100);
		}
		
		[AfterClass]
		public static function tearDownAfterClass():void
		{
			_testUtility.dispose();
			UIImpersonator.removeAllChildren();
		}
		
		[Test(order=1)]
		public function mediator_lifecycle_should_be_executed():void
		{
			// Activation should be triggered at the end of lifecycle.
			assertThat(_mediator.lifecycleOrder, 
				array(LifecycledMediator.PERSISTED, LifecycledMediator.INITIATE, 
					LifecycledMediator.COMPLETE, ActivatableMediator.ACTIVATED));
		}
		
		[Test(order=2,async)]
		public function mediator_should_be_not_active_when_view_invisible():void
		{
			_view.visible = false;
			
			Async.delayCall(this, function():void
			{
				assertThat(_mediator.activated, isFalse());
			}, 50);
		}
		
		[Test(order=3,async)]
		public function mediator_should_be_active_when_view_visible():void
		{
			_view.visible = true;
			
			Async.delayCall(this, function():void
			{
				assertThat(_mediator.activated, isTrue());
			}, 50);
		}
		
		[Test(order=4,async)]
		public function mediator_should_be_not_active_when_view_removed_from_stage():void
		{
			_moduleView.removeElement(_view);
			
			Async.delayCall(this, function():void
			{
				assertThat(_mediator.activated, isFalse());
				assertThat(_mediator.destroyed, isFalse());
			}, 50);
		}
		
		[Test(order=5,async)] 
		public function mediator_should_be_active_when_view_added_to_stage():void
		{
			_moduleView.addElement(_view);
			
			Async.delayCall(this, function():void
			{
				assertThat(_mediator.activated, isTrue());
			}, 50);
		}
		
		[Test(order=6)]
		public function mediator_should_be_not_active_when_view_not_added_to_stage_but_visible():void
		{
			assertThat(_pendentMediator.activated, isFalse());
		}
		
		[Test(order=7,async)]
		public function mediator_should_be_not_active_when_ancestor_view_invisible():void
		{
			_moduleView.visible = false;
			
			Async.delayCall(this, function():void
			{
				assertThat(_mediator.activated, isFalse());
			}, 50);
		}
		
		[Test(order=8,async)]
		public function mediator_should_be_active_when_ancestor_view_visible():void
		{
			_moduleView.visible = true;
			
			Async.delayCall(this, function():void
			{
				assertThat(_mediator.activated, isTrue());
			}, 50);
		}
		
		[Test(order=9,async)]
		public function mediator_should_be_not_active_when_ancestor_removed_from_stage():void
		{
			_moduleView.parent.removeChild(_moduleView);
			
			Async.delayCall(this, function():void
			{
				assertThat(_mediator.activated, isFalse());
			}, 50);
		}
		
		[Test(order=10,async)]
		public function mediator_should_be_active_when_ancestor_added_to_stage():void
		{
			UIImpersonator.addChild(_moduleView);
			
			Async.delayCall(this, function():void
			{
				assertThat(_mediator.activated, isTrue());
			}, 50);
		}
	}
}